package com.ruoyi.system.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Collections;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.service.ISysCourseService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.util.CollectionUtils;

/**
 * 课程管理Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-04-24
 */
@Service
public class SysCourseServiceImpl implements ISysCourseService 
{
    @Autowired
    private SysCourseMapper sysCourseMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysTestPaperMapper sysTestPaperMapper;

    @Autowired
    private SysSingleQuestionMapper sysSingleQuestionMapper;

    @Autowired
    private SysCourseStudyRecordMapper sysCourseStudyRecordMapper;

    @Autowired
    private SysCourseNodeMapper sysCourseNodeMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 查询课程管理
     * 
     * @param id 课程管理主键
     * @return 课程管理
     */
    @Override
    public SysCourse selectSysCourseById(Long id)
    {
        return sysCourseMapper.selectSysCourseById(id);
    }

    /**
     * 查询课程管理列表
     * 
     * @param sysCourse 课程管理
     * @return 课程管理
     */
    @Override
    public List<SysCourse> selectSysCourseList(SysCourse sysCourse)
    {
        return sysCourseMapper.selectSysCourseList(sysCourse);
    }

    /**
     * 新增课程管理
     * 
     * @param sysCourse 课程管理
     * @return 结果
     */
    @Override
    public int insertSysCourse(SysCourse sysCourse)
    {
        // 部门信息
        SysDept sysDept = sysDeptMapper.selectDeptById(sysCourse.getDeptId());
        // 设置部门名称
        sysCourse.setDepeName(sysDept.getDeptName());
        // 课程编码
        sysCourse.setCourseCode(IdUtils.fastSimpleUUID());
        // 设置创建时间 创建人
        sysCourse.setCreateBy(ShiroUtils.getLoginName());
        sysCourse.setCreateTime(DateUtils.getNowDate());
        return sysCourseMapper.insertSysCourse(sysCourse);
    }

    /**
     * 修改课程管理
     * 
     * @param sysCourse 课程管理
     * @return 结果
     */
    @Override
    public int updateSysCourse(SysCourse sysCourse)
    {
        // 设置更新人 更新时间
        sysCourse.setUpdateBy(ShiroUtils.getLoginName());
        sysCourse.setUpdateTime(DateUtils.getNowDate());
        return sysCourseMapper.updateSysCourse(sysCourse);
    }

    /**
     * 批量删除课程管理
     * 
     * @param ids 需要删除的课程管理主键
     * @return 结果
     */
    @Override
    public int deleteSysCourseByIds(String ids)
    {
        return sysCourseMapper.deleteSysCourseByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除课程管理信息
     * 
     * @param id 课程管理主键
     * @return 结果
     */
    @Override
    public int deleteSysCourseById(Long id)
    {
        return sysCourseMapper.deleteSysCourseById(id);
    }

    @Override
    public void testPaperGeneration(String id) {
        // 课程信息
        SysCourse sysCourse = this.selectSysCourseById(Long.valueOf(id));
        // 校验课程信息
        this.checkData(sysCourse);
        // 查询该课程题库
        List<SysSingleQuestion> sysSingleQuestions = this.findSysSingleQuestionByCourse(sysCourse.getId());
        SysTestPaper sysTestPaper = this.buildSysTestPaper(sysCourse, sysSingleQuestions);
        // 保存试卷内容
        sysTestPaperMapper.insertSysTestPaper(sysTestPaper);
    }

    @Override
    public void releaseCourses(String id) {
        // 课程信息
        SysCourse sysCourse = this.selectSysCourseById(Long.valueOf(id));
        // 查看有没有生成过学习记录
        this.checkIsReleaseCourses(sysCourse);
        // 查询课程小结，对每个学生生成学习视频
        List<SysCourseNode> sysCourseNodes = this.findSysCourseNodeList(sysCourse);
        // 查询班级下学生信息
        List<SysUser> sysUsers = this.findUserByDept(sysCourse.getDeptId());
        // 生成学习记录
        List<SysCourseStudyRecord> sysCourseStudyRecords = new ArrayList<>();
        for (SysCourseNode sysCourseNode : sysCourseNodes) {
            for (SysUser sysUser : sysUsers) {
                SysCourseStudyRecord sysCourseStudyRecord = getSysCourseStudyRecord(sysCourseNode, sysUser);
                sysCourseStudyRecords.add(sysCourseStudyRecord);
            }
        }
        sysCourseStudyRecords.parallelStream().forEach(sysCourseStudyRecord -> {
            sysCourseStudyRecordMapper.insertSysCourseStudyRecord(sysCourseStudyRecord);
        });
    }

    /**
     * 构造数据
     * @param sysCourseNode 课程节点信息
     * @param sysUser 用户信息
     * @return 学习记录
     */
    private SysCourseStudyRecord getSysCourseStudyRecord(SysCourseNode sysCourseNode, SysUser sysUser) {
        SysCourseStudyRecord sysCourseStudyRecord = new SysCourseStudyRecord();
        // 设置课程节点信息
        sysCourseStudyRecord.setCourseId(sysCourseNode.getCourseId());
        sysCourseStudyRecord.setCourseCode(sysCourseNode.getCourseCode());
        sysCourseStudyRecord.setCourseName(sysCourseNode.getCourseName());
        sysCourseStudyRecord.setCourseNodeName(sysCourseNode.getCourseNodeName());
        sysCourseStudyRecord.setVideoUrl(sysCourseNode.getVideoUrl());
        // 设置用户信息
        sysCourseStudyRecord.setUserId(sysUser.getUserId());
        sysCourseStudyRecord.setUserName(sysUser.getUserName());
        // 初始化学习状态
        sysCourseStudyRecord.setStatus("TO_BE_LEARNED"); // 初始状态设为"未学习"
        return sysCourseStudyRecord;
    }

    /**
     * 感觉部门ID 查询该部门下的学生
     * @param deptId 部门ID
     * @return 该部门下成员
     */
    public List<SysUser> findUserByDept(Long deptId) {
        SysUser sysUser = new SysUser();
        sysUser.setDeptId(deptId);
        List<SysUser> sysUsers = sysUserMapper.selectUserList(sysUser);
        if (CollectionUtils.isEmpty(sysUsers)) {
            throw new RuntimeException("该班级下没有学生信息，无法发起考试");
        }
        return sysUsers;
    }

    /**
     * 查询课程小结信息
     * @param sysCourse 课程信息
     * @return res
     */
    public List<SysCourseNode> findSysCourseNodeList(SysCourse sysCourse) {
        SysCourseNode sysCourseNode = new SysCourseNode();
        sysCourseNode.setCourseId(sysCourse.getId());
        List<SysCourseNode> sysCourseNodes = sysCourseNodeMapper.selectSysCourseNodeList(sysCourseNode);
        if (CollectionUtils.isEmpty(sysCourseNodes)) {
            throw new RuntimeException("课程小结没有维护无法发布课程");
        }
        return sysCourseNodes;
    }

    /**
     * 查看是否生成过课程了
     */
    public void checkIsReleaseCourses(SysCourse sysCourse) {
        SysCourseStudyRecord sysCourseStudyRecord = new SysCourseStudyRecord();
        sysCourseStudyRecord.setCourseId(sysCourse.getId());
        List<SysCourseStudyRecord> sysCourseStudyRecords = sysCourseStudyRecordMapper.selectSysCourseStudyRecordList(sysCourseStudyRecord);
        if (!CollectionUtils.isEmpty(sysCourseStudyRecords)) {
            throw new RuntimeException("学习记录已生成，请勿重复生成");
        }
    }

    /**
     * 查看是否已经生成过试题了
     * @param sysCourse 课程信息
     */
    public void checkData(SysCourse sysCourse) {
        SysTestPaper sysTestPaper = new SysTestPaper();
        sysTestPaper.setCourseId(sysCourse.getId());
        List<SysTestPaper> sysTestPapers = sysTestPaperMapper.selectSysTestPaperList(sysTestPaper);
        if (!CollectionUtils.isEmpty(sysTestPapers)) {
            throw new RuntimeException("该课程已经生成试卷信息了");
        }
    }

    /**
     * 根据课程ID查询题库
     */
    public List<SysSingleQuestion> findSysSingleQuestionByCourse(Long courseId) {
        SysSingleQuestion sysSingleQuestion = new SysSingleQuestion();
        sysSingleQuestion.setCourseId(courseId);
        return sysSingleQuestionMapper.selectSysSingleQuestionList(sysSingleQuestion);
    }

    /**
     * 生成试卷信息
     * @param sysCourse 课程信息
     * @param sysSingleQuestions 课程题库
     * @return 试卷信息
     */
    public SysTestPaper buildSysTestPaper(SysCourse sysCourse, List<SysSingleQuestion> sysSingleQuestions) {
        SysTestPaper sysTestPaper = new SysTestPaper();
        // 试卷标题
        String title = DateUtils.parseDateToStr("yyyy", sysCourse.getEndTime()) + "年度【" + sysCourse.getCourseName() + "】考试";
        sysTestPaper.setTitle(title);
        sysTestPaper.setCourseId(sysCourse.getId());
        sysTestPaper.setCourseName(sysCourse.getCourseName());
        sysTestPaper.setDeptId(sysCourse.getDeptId());
        sysTestPaper.setDeptName(sysCourse.getDepeName());
        sysTestPaper.setStartTime(new Date());
        sysTestPaper.setEndTime(new Date());
        sysTestPaper.setDuration(60L);

        // 计算题库总分
        long totalGrade = 0L;
        for (SysSingleQuestion question : sysSingleQuestions) {
            totalGrade += Long.parseLong(question.getGrade());
        }

        // 如果题库总分小于100分，则使用题库总分作为满分
        long targetGrade = Math.min(totalGrade, 100L);

        // 随机打乱题目顺序
        Collections.shuffle(sysSingleQuestions);

        // 选择题目直到达到目标分数
        List<SysSingleQuestion> selectedQuestions = new ArrayList<>();
        long currentGrade = 0L;

        for (SysSingleQuestion question : sysSingleQuestions) {
            long questionGrade = Long.parseLong(question.getGrade());
            if (currentGrade + questionGrade <= targetGrade) {
                selectedQuestions.add(question);
                currentGrade += questionGrade;
            }
            if (currentGrade >= targetGrade) {
                break;
            }
        }

        // 如果选中的题目总分不足目标分数，则使用所有题目
        if (currentGrade < targetGrade) {
            selectedQuestions = sysSingleQuestions;
            currentGrade = totalGrade;
        }

        // 设置试卷总分
        sysTestPaper.setGrade(currentGrade);

        // 初始化题库信息
        String extendedField = JSON.toJSONString(selectedQuestions);
        sysTestPaper.setExtendedField(extendedField);
        sysTestPaper.setCreateBy(ShiroUtils.getLoginName());
        sysTestPaper.setCreateTime(new Date());
        return sysTestPaper;
    }

}
